package org.jaaksi.demo.ptr.view;

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.*;
import org.jaaksi.demo.ptr.R;
import org.jaaksi.demo.ptr.util.DensityUtil;

/**
 * 自定义LoadMoreListView，能不能封装一个LoadMoreAdapterView extends AbsListView
 * 需要考虑没有数据时隐藏footer
 * 可以添加一个高度为wrap_content的footer,然后往里面添加view,如果有更多数据则显示view,没有就隐藏
 */
public class LoadMoreListView extends ListView
{
	/**
	 * footer的高度
	 */
	private final int FOOTER_HEIGHT = 50; // dp
	private LayoutInflater inflater;
	// 加载更多视图（底部视图）
	private LinearLayout footContainer;
	private View realFooter;
	// 加载更多文字
	private TextView tvFootTitle;
	// 加载更多忙碌框
	private ProgressBar pbFootRefreshing;
	// 是否还有数据标志
	private boolean hasMoreDataFlag;
	/**
	 * 是否滑动到底部后自动加载
	 */
	private boolean isAutoLoadMore = true;
	/**
	 * 是否显示没有更多提示footer
	 */
	private boolean isShowNoMore = true;
	/**
	 * 是否正在加载更多
	 */
	private boolean isLoadingMore = false;
	/**
	 * Scroll时到达最后一个Item的次数，只有第一次能触发自动刷新
	 */
	private int reachLastPositionCount = 0;
	private OnLoadMoreListener mLoadMoreListener;

	public LoadMoreListView(Context context)
	{
		this(context, null);
	}

	public LoadMoreListView(Context context, AttributeSet attrs)
	{
		this(context, attrs, 0);
	}

	public LoadMoreListView(Context context, AttributeSet attrs, int defStyle)
	{
		super(context, attrs, defStyle);
		init(context, attrs);
	}

	/**
	 * 初始化footerView
	 * 
	 * @return
	 */
	protected View initFooterView()
	{
		return inflater.inflate(R.layout.lib_loadmore_listview_footer, this,
		        false);
	}

	/**
	 * 初始化
	 *
	 * @param context
	 */
	private void init(Context context, AttributeSet attrs)
	{
		inflater = LayoutInflater.from(context);

		footContainer = new LinearLayout(context);
		footContainer.setOrientation(LinearLayout.VERTICAL);
		realFooter = initFooterView();
		realFooter.setVisibility(GONE);
		tvFootTitle = (TextView) realFooter.findViewById(R.id.lml_footer_text);
		pbFootRefreshing = (ProgressBar) realFooter
		        .findViewById(R.id.lml_footer_loading_progressbar);
		if (realFooter != null)
		{
			footContainer.addView(realFooter,
			        ViewGroup.LayoutParams.MATCH_PARENT,
			        DensityUtil.dip2px(context, FOOTER_HEIGHT));
		}

		// 滑动监听
		setOnScrollListener(new OnScrollListener()
		{

			@Override
			public void onScrollStateChanged(AbsListView view, int scrollState)
			{
				doOnScrollStateChanged(view, scrollState);

			}

			@Override
			public void onScroll(AbsListView view, int firstVisibleItem,
		            int visibleItemCount, int totalItemCount)
			{
				doOnScroll(view, firstVisibleItem, visibleItemCount,
		                totalItemCount);

			}
		});

	}

	/**
	 * @param isAutoLoadMore
	 *            是否滑到listview底部时自动加载
	 */
	public void setAutoLoadMore(boolean isAutoLoadMore)
	{
		this.isAutoLoadMore = isAutoLoadMore;
		if (!isAutoLoadMore)
		{
			realFooter.setOnClickListener(new OnClickListener()
			{
				@Override
				public void onClick(View view)
				{
					if (!isLoadingMore && hasMoreDataFlag
			                && mLoadMoreListener != null)
					{
						loadingMore();
					}
				}
			});
		}
	}

	/**
	 * 加载更多
	 */
	private void loadingMore()
	{
		isLoadingMore = true;
		realFooter.setVisibility(VISIBLE);
		pbFootRefreshing.setVisibility(View.VISIBLE);
		tvFootTitle.setText("正在加载...");
		mLoadMoreListener.onLoadMore();
	}

	/**
	 * 判断是否可以自动加载更多<br/>
	 * 优化这个方法，现在存在一个bug，如果设置不自动加载，出按钮， 但是默认是隐藏的，滑到底部时就chubu
	 *
	 * @return
	 */
	private boolean checkCanLoadMore()
	{
		if (getLastVisiblePosition() != getAdapter().getCount() - 1)
		{
			return false;
		}
		if (!canScroll(1) && !canScroll(-1))
		{ // TODO
			return false;
		}
		if (isLoadingMore)
		{
			return false;
		}
		if (!hasMoreDataFlag)
		{
			return false;
		}
		if (mLoadMoreListener == null)
		{
			return false;
		}
		// if (!iaAutoLoadMore && reachLastPositionCount != 1)
		// {
		// return false;
		// }
		return true;
	}

	/**
	 * 判断ListView是否可以滑动
	 *
	 * @param direction
	 * @return
	 */
	private boolean canScroll(int direction)
	{
		final int childCount = getChildCount();
		if (childCount == 0)
		{
			return false;
		}

		final int firstPosition = getFirstVisiblePosition();
		final int listPaddingTop = getPaddingTop();
		final int listPaddingBottom = getPaddingBottom();
		final int itemCount = getAdapter().getCount();

		if (direction > 0)
		{
			final int lastBottom = getChildAt(childCount - 1).getBottom();
			final int lastPosition = firstPosition + childCount;
			return lastPosition < itemCount
			        || lastBottom > getHeight() - listPaddingBottom;
		}
		else
		{
			final int firstTop = getChildAt(0).getTop();
			return firstPosition > 0 || firstTop < listPaddingTop;
		}
	}

	public void setOnLoadMoreListener(OnLoadMoreListener onLoadMoreListener)
	{
		mLoadMoreListener = onLoadMoreListener;
		addFooterView(footContainer);

	}

	private void showMoreButton()
	{
		tvFootTitle.setText("加载更多");
		realFooter.setVisibility(VISIBLE);
	}

	private void loadMoreComplete()
	{
		isLoadingMore = false;
		pbFootRefreshing.setVisibility(View.GONE);

		if (hasMoreDataFlag)
		{
			if (isAutoLoadMore)
			{
				realFooter.setVisibility(GONE);
			}
			else
			{
				showMoreButton();
			}
		}
		else
		{
			tvFootTitle.setText("没有更多啦");
			if (isShowNoMore)
			{
				realFooter.setVisibility(VISIBLE);
			}
			else
			{
				realFooter.setVisibility(GONE);
			}
		}
	}

	/**
	 * 在加载完成后调用
	 * 
	 * @param hashMore
	 *            是否有更多数据
	 */
	public void setHasMore(boolean hashMore)
	{
		hasMoreDataFlag = hashMore;
		loadMoreComplete();
	}

	/**
	 * 如果项目中其他地方需要重新设置GetMoreListView的OnScrollListener<br/>
	 * 请在新的listener中onScrollStateChanged方法内调用此方法，保证PullListView正常运行。
	 *
	 * @param view
	 * @param scrollState
	 */
	public void doOnScrollStateChanged(AbsListView view, int scrollState)
	{

		switch (scrollState)
		{
			case OnScrollListener.SCROLL_STATE_TOUCH_SCROLL:
				break;
			case OnScrollListener.SCROLL_STATE_FLING:
				// 滑动时候停止加载图片
				// ImageLoader.getInstance().pause();
				break;

			case OnScrollListener.SCROLL_STATE_IDLE:
				// 停下后恢复加载图片
				// ImageLoader.getInstance().resume();
				break;
			default:
				break;
		}

	}

	/**
	 * 如果项目中其他地方需要重新设置LoadMoreListView的OnScrollListener<br/>
	 * 请在新的listener中onScroll方法内调用此方法，保证PullListView正常运行。
	 *
	 * @param view
	 * @param firstVisibleItem
	 * @param visibleItemCount
	 * @param totalItemCount
	 */
	public void doOnScroll(AbsListView view, int firstVisibleItem,
	        int visibleItemCount, int totalItemCount)
	{
		if (getAdapter() == null)
		{
			return;
		}

		// if (getLastVisiblePosition() == getAdapter().getCount() - 1)
		// {
		// reachLastPositionCount++;
		// }
		// else
		// {
		// reachLastPositionCount = 0;
		// }

		if (checkCanLoadMore())
		{
			if (isAutoLoadMore)
			{
				loadingMore();
			}
			else
			{ // 显示“加载更多”按钮
				showMoreButton();
			}
		}

	}

	/**
	 * 加载更多接口
	 */
	public interface OnLoadMoreListener
	{
		void onLoadMore();
	}

}
